home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1994 November / macformat-018.iso / Utility Spectacular / Developer / PTR-TCL v2.1 / 3) inherited fixer / Munge.c < prev   
Encoding:
C/C++ Source or Header  |  1994-01-15  |  7.2 KB  |  318 lines  |  [TEXT/MMCC]

  1. /*
  2.  * munge.c
  3.  */
  4.  
  5. #include <string.h>
  6.  
  7. extern int * sprintf ( char * , const char * , ... ) ;
  8. unsigned char * C2P ( char * ) ;
  9.  
  10.  
  11. /*    0 == whitespace
  12.     1 == line feed chars
  13.     2 == digit
  14.     3 == colon
  15.     4 == letter
  16.     5 == bracket
  17.     6 == bracket
  18.     */
  19.  
  20. char ch_type [ ] = {
  21. /*        0,    1,    2,    3,    4,    5,    6,    7,    8,    9,    A,    B,    C,    D,    E,    F */
  22. /* 0 */    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    1,    0,    0,
  23. /* 1 */    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  24. /* 3 */    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  25. /* 2 */    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    3,    0,    0,    0,    0,    0,
  26. /* 4 */    0,    4,    4,    4,    4,    4,    4,    4,    4,    4,    4,    4,    4,    4,    4,    4,
  27. /* 5 */    4,    4,    4,    4,    4,    4,    4,    4,    4,    4,    4,    0,    0,    0,    0,    4,
  28. /* 6 */    0,    4,    4,    4,    4,    4,    4,    4,    4,    4,    4,    4,    4,    4,    4,    4,
  29. /* 7 */    4,    4,    4,    4,    4,    4,    4,    4,    4,    4,    4,    5,    0,    6,    0,    0,
  30. /* 8 */    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  31. /* 9 */    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  32. /* A */    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  33. /* B */    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  34. /* C */    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  35. /* D */    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  36. /* E */    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  37. /* F */    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  38. } ;
  39.  
  40.  
  41. extern void Idle ( void ) ;
  42. extern short vRefNum ;
  43. void MungeFolder ( long parID ) ;
  44. extern void Message ( unsigned char * ) ;
  45. extern Boolean DoLine ( unsigned char * line ) ;
  46. extern void LookupParent ( char * child , char * parent ) ;
  47.  
  48.  
  49. CInfoPBRec rec ;
  50. short err ;
  51. Str63 name ;
  52. Str255 str ;
  53. short lineNo ;
  54.  
  55.  
  56. static void
  57. CopyP ( unsigned char * from , unsigned char * to ) {
  58.     BlockMove ( from , to , 1 + * from ) ;
  59. }
  60.  
  61.  
  62. static void
  63. ConcP ( unsigned char * to , unsigned char * tail ) {
  64.  
  65. short len = * tail ;
  66.     if ( len + * to > 255 ) {
  67.         len = 255 - * to ;
  68.     }
  69.     BlockMove ( tail + 1 , to + * to + 1 , len ) ;
  70.     * to += len ;
  71. }
  72.  
  73.  
  74. unsigned char *
  75. C2P ( char * c ) {
  76. int len = strlen ( c ) ;
  77.     if ( len ) {
  78.         BlockMove ( c , c + 1 , len ) ;
  79.     }
  80.     * c = len ;
  81.     return ( unsigned char * ) c ;
  82. }
  83.  
  84.  
  85. static void
  86. ErrMsg ( unsigned char * why , unsigned char * file , short code ) {
  87.  
  88. Str15 nn ;
  89. long tick ;
  90. static long lastBeep = 0 ;
  91.  
  92.     NumToString ( code , nn ) ;
  93.     CopyP ( "\p ERROR " , str ) ;
  94.     ConcP ( str , why ) ;
  95.     ConcP ( str , "\p " ) ;
  96.     ConcP ( str , nn ) ;
  97.     ConcP ( str , "\p\r" ) ;
  98.     Message ( str ) ;
  99.     tick = TickCount ( ) + 5 ;
  100.     if ( lastBeep < tick - 600 ) { /* Only beep every 10 seconds if lots of errors */
  101.         SysBeep ( 20 ) ;
  102.         lastBeep = tick ;
  103.     }
  104. }
  105.  
  106.  
  107. static long
  108. token ( Handle text , long pos , long end , char * tok , long * before ) {
  109.  
  110. char type ;
  111.  
  112.     while ( pos < end ) {
  113.         while ( ! ch_type [ ( * text ) [ pos ] ] && pos < end ) { // Skip junk
  114.             pos ++ ;
  115.         }
  116.         * before = pos ;
  117.         * tok = ( * text ) [ pos ] ; // First token char
  118.         pos ++ ;
  119.         type = ch_type [ * tok ] ;
  120.         tok ++ ;
  121.         if ( type == 1 ) { // line break
  122.             * tok = 0 ;
  123.             return pos ;
  124.         }
  125.         while ( pos < end ) {
  126.         char xTyp = ch_type [ ( * text ) [ pos ] ] ;
  127.             if ( ( xTyp != type ) &&
  128.                 ! ( type == 4 && xTyp == 2 ) ) { // Identifier number
  129.                 * tok = 0 ;
  130.                 return pos ;
  131.             }
  132.             * ( tok ++ ) = ( * text ) [ pos ++ ] ;
  133.         }
  134.     }
  135.     * tok = 0 ;
  136.     return end ;
  137. }
  138.  
  139.  
  140. static int
  141. Replace ( Handle text , long pos , long len , char * with ) {
  142.     Munger ( text , pos , NULL , len , with , strlen ( with ) ) ;
  143.     return strlen ( with ) - len ;
  144. }
  145.  
  146.  
  147. /* This function contains the total text of a TEXT file. */
  148. /* The contents of the handle will be re-written to disk when done if true returned. */
  149. /* Call Idle ( ) now and then for lengthy tasks */
  150. static Boolean
  151. MungeHandle ( Handle text ) {
  152.  
  153. long end = GetHandleSize ( text ) ;
  154. long pos = 0 ;
  155. char tok [ 256 ] ;
  156. char className [ 256 ] ;
  157. char other [ 256 ] ;
  158. long before = 0 ;
  159. long level = 0 ;
  160. long oldPos ;
  161. long oldBefore ;
  162. int line = 1 ;
  163. Boolean chng = 0 ;
  164.  
  165.     className [ 0 ] = 0 ;
  166.     tok [ 0 ] = 0 ;
  167.     while ( pos < end ) {
  168.         oldPos = pos ;
  169.         oldBefore = before ;
  170.         tok [ 0 ] = 0 ;
  171.         pos = token ( text , pos , end , tok , & before ) ;
  172.         if ( ! tok [ 0 ] ) {
  173.             break ;
  174.         }
  175.         if ( ch_type [ tok [ 0 ] ] == 1 ) {
  176.             line ++ ;
  177.             if ( ! ( line % 10 ) ) {
  178.                 Idle ( ) ;
  179.             }
  180.         }
  181.         if ( level ) {
  182.             if ( ! strcmp ( tok , "inherited" ) ) {
  183.             int delta = Replace ( text , before , 9 , className ) ;
  184.                 pos += delta ;
  185.                 end += delta ;
  186.                 chng = true ;
  187.             } else if ( ! strcmp ( tok , "{" ) ) {
  188.                 level ++ ;
  189.             } else if ( ! strcmp ( tok , "}" ) ) {
  190.                 level -- ;
  191.             }
  192.         } else { // no level - set context ?
  193.             if ( ! strcmp ( tok , "::" ) ) {
  194.                 strncpy ( other , ( * text ) + oldBefore , oldPos - oldBefore ) ;
  195.                 other [ oldPos - oldBefore ] = 0 ;
  196.                 LookupParent ( other , className ) ;
  197.                 if ( ! className [ 0 ] ) {
  198.                     sprintf ( className , "\rLine %d: Unknown superclass" , line ) ;
  199.                     Message ( C2P ( className ) ) ;
  200.                     strcpy ( className , "/*UNKNOWN_SUPERCLASS*/" ) ;
  201.                 }
  202.             } else if ( ! strcmp ( tok , "{" ) ) {
  203.                 level ++ ;
  204.             } else if ( ! strcmp ( tok , "}" ) ) {
  205.                 sprintf ( other , "\r• Error Line %d: level < 0 " , line ) ;
  206.                 Message ( C2P ( other ) ) ;
  207.             }
  208.         }
  209.     }
  210.     return true ;
  211. }
  212.  
  213.  
  214. static void
  215. MungeFile ( short vRef , long parID , unsigned char * fn ) {
  216.  
  217. Handle text ;
  218. short ref = 0 ;
  219. long size ;
  220. Boolean doWrite ;
  221.  
  222.     Message ( fn ) ;
  223.  
  224.     err = HOpenDF ( vRef , parID , fn , fsRdWrPerm , & ref ) ;
  225.     if ( err ) {
  226.         ErrMsg ( "\pOpening" , fn , err ) ;
  227.         return ;
  228.     }
  229.     err = GetEOF ( ref , & size ) ;
  230.     if ( ! err ) {
  231.         err = SetFPos ( ref , fsFromStart , 0L ) ;
  232.     }
  233.     if ( err ) {
  234.         ErrMsg ( "\pStarting" , fn , err ) ;
  235.         FSClose ( ref ) ;
  236.         return ;
  237.     }
  238.     text = NewHandle ( size ) ;
  239.     if ( ! text ) {
  240.         ErrMsg ( "\pAllocating" , fn , MemError ( ) ) ;
  241.         FSClose ( ref ) ;
  242.         return ;
  243.     }
  244.     HLock ( text ) ;
  245.     err = FSRead ( ref , & size , * text ) ;
  246.     if ( err ) {
  247.         ErrMsg ( "\pReading" , fn , err ) ;
  248.         FSClose ( ref ) ;
  249.         DisposeHandle ( text ) ;
  250.     }
  251.     HUnlock ( text ) ;
  252.     doWrite = MungeHandle ( text ) ;
  253.     if ( doWrite ) {
  254.         size = GetHandleSize ( text ) ;
  255.         err = SetEOF ( ref , size ) ;
  256.         if ( ! err ) {
  257.             err = SetFPos ( ref , fsFromStart , 0L ) ;
  258.         }
  259.         if ( err ) {
  260.             ErrMsg ( "\pFinishing" , fn , err ) ;
  261.             FSClose ( ref ) ;
  262.             DisposeHandle ( text ) ;
  263.             return ;
  264.         }
  265.         HLock ( text ) ;
  266.         err = FSWrite ( ref , & size , * text ) ;
  267.         if ( err ) {
  268.             ErrMsg ( "\pWriting" , fn , err ) ;
  269.             FSClose ( ref ) ;
  270.             DisposeHandle ( text ) ;
  271.             return ;
  272.         }
  273.     }
  274.     err = FSClose ( ref ) ;
  275.     if ( doWrite && ! err ) {
  276.         err = FlushVol ( NULL , vRef ) ;
  277.     }
  278.     DisposeHandle ( text ) ;
  279.     if ( err ) {
  280.         ErrMsg ( "\pClosing" , fn , err ) ;
  281.     }
  282.     Message ( "\p DONE\r" ) ;
  283. }
  284.  
  285.  
  286. void
  287. MungeFolder ( long parID ) {
  288.  
  289. short ix ;
  290.  
  291.     for ( ix = 1 ; ix > 0 ; ix ++ ) {
  292.         rec . hFileInfo . ioCompletion = 0L ;
  293.         rec . hFileInfo . ioFVersNum = 0 ;
  294.         rec . hFileInfo . ioNamePtr = name ;
  295.         rec . hFileInfo . ioVRefNum = vRefNum ;
  296.         rec . hFileInfo . ioDirID = parID ;
  297.         rec . hFileInfo . ioFDirIndex = ix ;
  298.         err = PBGetCatInfoAsync ( & rec ) ;
  299.         do {
  300.             Idle ( ) ;
  301.         } while ( rec . hFileInfo . ioResult == 1 ) ;
  302.         err = rec . hFileInfo . ioResult ;
  303.         if ( err ) {
  304.             break ;
  305.         }
  306.         if ( rec . hFileInfo . ioFlAttrib & 0x10 ) { /* Folder */
  307.             CopyP ( "\p\r•Entering Folder " , str ) ;
  308.             ConcP ( str , name ) ;
  309.             ConcP ( str , "\p\r" ) ;
  310.             Message ( str ) ;
  311.             MungeFolder ( rec . hFileInfo . ioDirID ) ;
  312.             Message ( "\p---- Leaving folder ----\r\r" ) ;
  313.         } else if ( rec . hFileInfo . ioFlFndrInfo . fdType == 'TEXT' ) {
  314.             MungeFile ( vRefNum , parID , name ) ;
  315.         }
  316.     }
  317. }
  318.